package com.gitee.techstack.nacos.controller;

import com.alibaba.nacos.api.common.Constants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @author Yeoman
 * @description
 * @create 2020/1/17 上午8:56
 **/
@Controller
public class NacosConfigController {

     ScheduledExecutorService scheduler;
    /**
     * 比较MD5
     */
    @RequestMapping(value = "/listener", method = RequestMethod.POST)
    public void listener(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
//        String probeModify = request.getParameter("Listening-Configs");
//        if (StringUtils.isBlank(probeModify)) {
//            // throw new IllegalArgumentException("invalid probeModify");
//        }
//
//        probeModify = URLDecoder.decode(probeModify, Constants.ENCODE);
//
//        Map<String, String> clientMd5Map;
//        try {
////            clientMd5Map = MD5Util.getClientMd5Map(probeModify);
//        } catch (Throwable e) {
//            throw new IllegalArgumentException("invalid probeModify");
//        }

        // do long-polling
        //inner.doPollingConfig(request, response, clientMd5Map, probeModify.length());

        doPollingConfig(request, response, null, 1);
    }

    /**
     * 轮询接口
     */
    @SuppressWarnings("PMD.ThreadPoolCreationRule")
    public void doPollingConfig(HttpServletRequest request, HttpServletResponse response,
                                  Map<String, String> clientMd5Map, int probeRequestSize)
            throws IOException, ServletException {

        scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setDaemon(true);
                t.setName("com.alibaba.nacos.LongPolling");
                return t;
            }
        });

        final AsyncContext asyncContext = request.startAsync();
        // AsyncContext.setTimeout()的超时时间不准，所以只能自己控制
        asyncContext.setTimeout(0L);
        scheduler.execute(new Test(asyncContext));
//        scheduler.scheduleWithFixedDelay(new Test(), 0L, 10L, TimeUnit.SECONDS);

//        // 长轮询
//        if (LongPollingService.isSupportLongPolling(request)) {
//            longPollingService.addLongPollingClient(request, response, clientMd5Map, probeRequestSize);
//            return HttpServletResponse.SC_OK + "";
//        }
//
//        // else 兼容短轮询逻辑
//        List<String> changedGroups = MD5Util.compareMd5(request, response, clientMd5Map);
//
//        // 兼容短轮询result
//        String oldResult = MD5Util.compareMd5OldResult(changedGroups);
//        String newResult = MD5Util.compareMd5ResultString(changedGroups);
//
//        String version = request.getHeader(Constants.CLIENT_VERSION_HEADER);
//        if (version == null) {
//            version = "2.0.0";
//        }
//        int versionNum = Protocol.getVersionNumber(version);
//
//        /**
//         * 2.0.4版本以前, 返回值放入header中
//         */
//        if (versionNum < START_LONGPOLLING_VERSION_NUM) {
//            response.addHeader(Constants.PROBE_MODIFY_RESPONSE, oldResult);
//            response.addHeader(Constants.PROBE_MODIFY_RESPONSE_NEW, newResult);
//        } else {
//            request.setAttribute("content", newResult);
//        }



    }


    public class Test implements Runnable {

        final AsyncContext asyncContext;
        Future<?> asyncTimeoutFuture;
        long timeoutTime;

        public Test(AsyncContext asyncContext){
            this.asyncContext = asyncContext;
            this.timeoutTime = 3500;
        }

        @Override
        public void run() {


            asyncTimeoutFuture = scheduler.schedule(new Runnable() {
                @Override
                public void run() {
                    try {
                        try {

                            HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();

                            String respString = "5000";

                            // 禁用缓存
                            response.setHeader("Pragma", "no-cache");
                            response.setDateHeader("Expires", 0);
                            response.setHeader("Cache-Control", "no-cache,no-store");
                            response.setStatus(HttpServletResponse.SC_OK);
                            response.getWriter().println(respString);
                            asyncContext.complete();
                        } catch (Exception se) {
                        }
                    } catch (Throwable t) {
                    }

                }
            }, timeoutTime, TimeUnit.MILLISECONDS);

//            allSubs.add(this);



        }
    }

}
